package com.tz.example.single;

import java.lang.reflect.Constructor;

/**
 * 枚举式饿汉单例
 * 特点：
 * 1.线程安全，枚举对象，在类加载时创建，不存在线程不安全问题
 * 2.无法通过反射破解
 * 3.类加载就创建，而不是调用getInstance()方法时对创建，不是延迟加载
 * 4.获取和创建过程都没同步锁，不存在多线程下的同步开销问题
 * @author zhangyuetao
 */
public enum EnumHungrySingle {
    INSTANCE("枚举创建");
    private String from;

    private EnumHungrySingle(String from) {
        this.from = from;
    }

    public String getFrom() {
        return from;
    }

    public static EnumHungrySingle getInstance() {
        return INSTANCE;
    }

    public static void main(String[] args) throws Exception {
        //多线程跑
        for (int i = 0; i < 10; i++) {
            new Thread() {
                @Override
                public void run() {
                    EnumHungrySingle instance = EnumHungrySingle.getInstance();
                    System.out.println(instance.toString() + "---from:" + instance.getFrom());
                }
            }.start();
        }
        //反射创建测试，结果会报“java.lang.IllegalArgumentException: Cannot reflectively create enum objects”
        Constructor<EnumHungrySingle> declaredConstructor = EnumHungrySingle.class.getDeclaredConstructor(String.class, int.class, String.class);
        declaredConstructor.setAccessible(Boolean.TRUE);
        EnumHungrySingle instance2 = declaredConstructor.newInstance("反射");
        System.out.println(instance2.toString() + "---from:" + instance2.getFrom());
    }
}
